package com.thread.threadfirst.studyThread1;

import java.util.concurrent.TimeUnit;

/**
 * 8、可重入锁
 * synchronized获得的锁是可重入的
 * 一个同步方法可以调用另一个同步方法，一个线程获得某个对象的锁时，再次申请的时候仍然可以得到该对象的锁（注意：前提是同一个线程）
 * 还有种情况：在继承关系中，子类的同步方法调用父类的同步方法
 */
public class T {
    public synchronized void m1() {
        System.out.println("m1 start");
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        m2();
    }

    public synchronized void m2() {
        System.out.println("m2 start");
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("m2");
    }

    public synchronized void m() {
        System.out.println("m start");
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("m end");
    }

    public static void main(String[] args) {
//        第一种情况：
//        T t = new T();
//        new Thread(() -> t.m1()).start();

//        第二种情况：
        new TT().m();
    }
}

class TT extends T {
    @Override
    public synchronized void m() {
        System.out.println("child m start");
        super.m();
        System.out.println("child m end");
    }
}
